/**
 * Folo 应用入口文件
 *
 * 功能概述：
 * 此文件是 Folo 桌面应用的核心入口点，负责初始化整个 React 应用程序，
 * 配置运行环境，设置全局上下文，并将应用渲染到 DOM 中。
 *
 * 主要职责：
 * 1. 导入并配置核心样式和性能分析工具
 * 2. 设置全局上下文提供者（Context Providers）
 * 3. 初始化应用状态和服务
 * 4. 处理不同平台（Electron/Web）的特定配置
 * 5. 渲染 React 组件树
 *
 * 运行环境：
 * - 支持 Web 浏览器环境
 * - 支持 Electron 桌面环境
 * - 根据操作系统（Windows/macOS）自动应用不同样式
 *
 * 技术栈：
 * - React 框架
 * - React Router 路由管理
 * - Context API 状态管理
 * - TypeScript 类型系统
 * - Tailwind CSS 样式框架
 */

/*
 * 应用入口文件 - main.tsx
 * 此文件是应用的主要入口点，负责初始化React应用、配置环境、设置上下文
 * 以及渲染应用程序到DOM中
 */

// 导入性能分析工具，用于在开发过程中检测潜在的性能问题
// 性能分析工具(WDYR - Why Did You Render)帮助开发者识别不必要的组件渲染
import "./wdyr"
// 导入Tailwind CSS样式框架的基础配置
// 这将导入所有必要的Tailwind工具类和配置
import "@follow/components/tailwind"
// 导入项目的主样式文件
// 包含应用程序的全局CSS样式和自定义样式
import "./styles/main.css"

/*
 * 环境常量导入
 * 这些常量定义了应用程序的运行环境
 */
// 从共享常量中导入应用运行环境的标识
// IN_ELECTRON: 标识应用是否在Electron环境中运行
// WEB_BUILD: 标识应用是否以Web形式构建
import { IN_ELECTRON, WEB_BUILD } from "@follow/shared/constants"
/*
 * 上下文(Context)导入
 * 这些上下文用于在React组件树中共享状态和功能
 */
import { apiContext, authClientContext, queryClientContext } from "@follow/store/context"
// 导入操作系统检测工具，用于识别用户运行的操作系统类型
import { getOS } from "@follow/utils/utils"
/*
 * React核心库和相关工具导入
 */
// 导入React核心库
import * as React from "react"
// 从react-dom中导入flushSync函数，用于同步执行状态更新
// 在某些情况下需要确保状态更新立即反映到DOM中
import { flushSync } from "react-dom"
// 导入react-dom/client，用于创建React应用的根节点
import ReactDOM from "react-dom/client"
// 从react-router/dom中导入RouterProvider组件，用于提供路由功能
import { RouterProvider } from "react-router/dom"

/*
 * 应用核心服务和工具导入
 */
// 导入认证客户端实例，处理用户身份验证和授权
import { authClient } from "~/lib/auth"

// 从应用状态管理中导入设置应用就绪状态的函数
import { setAppIsReady } from "./atoms/app"
// 从常量文件中导入Electron自定义标题栏的高度值
import { ElECTRON_CUSTOM_TITLEBAR_HEIGHT } from "./constants"
// 导入应用初始化函数，用于执行应用启动时的必要设置
import { initializeApp } from "./initialize"
// 导入全局快捷键注册函数
import { registerAppGlobalShortcuts } from "./initialize/global-shortcuts"
// 导入自定义的API客户端实例
import { followApi } from "./lib/api-client"
// 导入查询客户端实例（用于数据获取和缓存管理）
import { queryClient } from "./lib/query-client"
// 导入路由配置
import { router } from "./router"
// 导入日志工具（尝试使用项目内部日志器，如果不可用则默认使用console）
let logger
try {
  // 尝试导入项目内部日志器
  logger = require("@follow/internal/logger").default || console
} catch {
  // 如果导入失败，使用console作为备选
  logger = console
}

// eslint-disable-next-line no-console
console.log("[App Bootstrap] Application initialization started")

// 记录当前运行环境信息
logger.log("[App Environment] IN_ELECTRON:", IN_ELECTRON, "WEB_BUILD:", WEB_BUILD)

/*
 * 上下文提供者设置
 * 这些提供器将核心服务注入到React组件树中，使子组件可以访问这些服务
 */
// 提供认证客户端到应用上下文中
authClientContext.provide(authClient)
logger.log("[Context Setup] Auth client context configured")

// 将查询客户端实例注入到对应的上下文中，使整个应用可以进行数据获取和缓存管理
// QueryClient负责API请求、缓存管理和数据同步
queryClientContext.provide(queryClient)
logger.log("[Context Setup] Query client context configured")

// 将自定义API客户端实例注入到对应的上下文中
// followApi封装了与后端服务通信的所有方法
apiContext.provide(followApi)
logger.log("[Context Setup] API client context configured")

/*
 * 应用初始化流程
 * 执行应用核心初始化过程，加载必要资源，设置初始状态
 */
// 执行应用初始化，并在初始化完成后执行后续操作
logger.log("[App Initialization] Starting initializeApp()...")
initializeApp().finally(() => {
  logger.log("[App Initialization] InitializeApp() completed")

  /*
   * 推送通知模块的条件加载
   * 使用动态导入技术，仅在需要时加载推送通知相关代码
   */
  if (navigator.serviceWorker && WEB_BUILD) {
    logger.log("[Push Notification] Service worker available, registering web push notifications")
    import("./push-notification")
      .then(({ registerWebPushNotifications }) => {
        registerWebPushNotifications()
        logger.log("[Push Notification] Web push notifications registered successfully")
      })
      .catch((error) => {
        logger.error("[Push Notification] Failed to register web push notifications:", error)
      })
  } else {
    logger.log("[Push Notification] Web push notifications skipped:", {
      serviceWorkerAvailable: !!navigator.serviceWorker,
      webBuild: WEB_BUILD,
    })
  }

  /*
   * 设置应用就绪状态
   * 使用flushSync确保状态更新立即生效，避免潜在的渲染延迟
   */
  // 使用flushSync同步设置应用就绪状态，确保状态更新立即生效
  // eslint-disable-next-line @eslint-react/dom/no-flush-sync
  flushSync(() => {
    setAppIsReady(true)
    logger.log("[App State] Application is now ready")
  })
})

/*
 * DOM元素获取
 * 获取应用程序的根容器元素，用于挂载React应用
 */
// 获取HTML文档中的根容器元素，用于挂载React应用
const $container = document.querySelector("#root") as HTMLElement
if (!$container) {
  logger.error("[DOM] Root container element not found! Cannot mount React application.")
}

/*
 * 平台特定配置
 * 根据不同的运行环境(Electron/Web)和操作系统类型进行特定配置
 */
// 检查应用是否在Electron环境中运行
if (IN_ELECTRON) {
  // 获取当前操作系统类型
  const os = getOS()
  logger.log("[Platform Configuration] Running in Electron environment on", os)

  // 根据不同操作系统设置相应的样式
  switch (os) {
    // Windows系统特殊处理
    case "Windows": {
      // 为Windows系统设置自定义标题栏的样式
      // 这确保应用窗口有正确的内边距，避免内容被窗口控件遮挡
      document.body.style.cssText += `--fo-window-padding-top: ${ElECTRON_CUSTOM_TITLEBAR_HEIGHT}px;`
      logger.log("[Platform Configuration] Applied Windows-specific styles")
      break
    }
    // macOS系统特殊处理
    case "macOS": {
      // 为macOS系统设置交通灯(窗口控制按钮)的样式
      // 这些CSS变量控制交通灯按钮的位置和尺寸
      document.body.style.cssText += `--fo-macos-traffic-light-width: 80px; --fo-macos-traffic-light-height: 30px;`
      logger.log("[Platform Configuration] Applied macOS-specific styles")
      break
    }
    default: {
      logger.log("[Platform Configuration] Unknown OS detected:", os)
    }
  }
  // 在HTML根元素上设置操作系统数据属性，用于CSS样式判断
  // 这允许CSS根据不同操作系统应用特定样式
  document.documentElement.dataset.os = getOS()
  logger.log("[Platform Configuration] Set OS data attribute:", getOS())
} else {
  // 如果不是在Electron环境中运行，则注册全局快捷键
  // Web版本中需要特殊的快捷键处理
  logger.log("[Platform Configuration] Running in Web environment, registering global shortcuts")
  registerAppGlobalShortcuts()
  logger.log("[Platform Configuration] Global shortcuts registered")
}

/*
 * 应用渲染
 * 创建React根节点并将应用渲染到DOM中
 */
// 创建React应用根节点并渲染应用
if ($container) {
  logger.log("[React Rendering] Starting React application rendering")
  try {
    ReactDOM.createRoot($container).render(
      // 使用严格模式包装应用，有助于在开发过程中发现潜在问题
      // 严格模式会激活额外的检查和警告，并识别不安全的生命周期方法
      <React.StrictMode>
        {/* // 提供路由功能，使应用支持页面导航
        // RouterProvider使用router配置定义应用的导航结构 */}
        <RouterProvider router={router} />
      </React.StrictMode>,
    )
    logger.log("[React Rendering] React application rendered successfully")
  } catch (error) {
    logger.error("[React Rendering] Failed to render React application:", error)
  }
}
